﻿#ifdef _WIN32
#include "windows_defines.h"
#endif

#include "../../../../../../unittest/framework/unittest.hh"
#include "box/service_context.hh"
#include "box/service_box.hh"
#include "util/time_util.hh"
#include "fwd.h"
#include <fstream>

FIXTURE_BEGIN(test_service_time_scheduler)

SETUP([]() {
        {
        std::ofstream ofs;
        ofs.open("config_test_service_time_scheduler.cfg", std::ios::trunc | std::ios::out);
        ofs << "listener = {\r"
            "   host = (\"127.0.0.1:10001\")\r"
            "}\r"

            "box_channel_recv_buffer_len = 1024\r"
            "box_name = \"test_guild\"\r"

            "service = {\r"
            "   service_dir = "
            "\"../../../../tmp\"\r"
            "}\r"

            "debugger = {\r"
            "   enable = \"true\"\r"
            "   listen = \"0.0.0.0:10888\"\r"
            "}\r"

            "service_finder = {\r"
            "   type = \"zookeeper\"\r"
            "   hosts = \"127.0.0.1:2181\"\r"
            "}\r"

            "statistics = {\r"
            "   is_open_rpc_stat = \"true\"\r"
            "}";
        ofs.close();
    }
})

CASE(TestServiceTimeScheduler1) {
    kratos::service::ServiceBox box;
    const char *argv_service[] = {"test_service_time_scheduler",
                                  "--config=config_test_time_scheduler.cfg",
                                  "--proxy-host=127.0.0.1:10002"};

    ASSERT_TRUE(box.start(3, argv_service));

    guild_service::common::singleton_start<guild_service::common::service_time_scheduler>(box.get_context());
    {
        auto ret = guild_service::time_schedule(
            0, [](std::uint64_t udata, std::time_t ms) -> bool {
                std::cout << "udata:" << udata << " ms:" << ms << '\n';
                return true;
            },
            123);
        std::cout << "ret:" << ret << '\n';
        ASSERT_TRUE(ret == 0);
    }

    guild_service::common::singleton_stop<guild_service::common::service_time_scheduler>();
    
    ASSERT_TRUE(box.stop());
}

CASE(TestServiceTimeScheduler2) {
    kratos::service::ServiceBox box;
    const char *argv_service[] = {"test_time_scheduler",
                                  "--config=config_test_time_scheduler.cfg",
                                  "--proxy-host=127.0.0.1:10002"};

    ASSERT_TRUE(box.start(3, argv_service));

    guild_service::common::singleton_start<guild_service::common::service_time_scheduler>(box.get_context());
    {
        std::cout << "add_time:" << kratos::util::get_os_time_millionsecond() << '\n';
        auto ret = guild_service::time_schedule(
            1000, [](std::uint64_t udata, std::time_t ms) -> bool {
                std::cout << "exec_time:" << kratos::util::get_os_time_millionsecond() << '\n';
                std::cout << "udata:" << udata << " ms:" << ms << '\n';
                return true;
            },
            456);
        std::cout << "ret:" << ret << '\n';
        ASSERT_TRUE(ret > 0);
    }
    std::time_t start_time = kratos::util::get_os_time_millionsecond();
    while (true)
    {
        std::time_t now = kratos::util::get_os_time_millionsecond();
        guild_service::common::singleton_update<guild_service::common::service_time_scheduler>(now);
        if (now - start_time > 5000)
        {
            break;
        }
    }
    guild_service::common::singleton_stop<guild_service::common::service_time_scheduler>();
 
    ASSERT_TRUE(box.stop());
}

FIXTURE_END(test_service_time_scheduler)